﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ATEC.GeometryNET;
using ATEC.GeometryNET.Common;
using ATEC.ATCoreNET;
using ATEC.ATDataCoreNET;
using ATEC.ATDataCoreNET.ATCCL;
using ATEC.CCLObj;
using SSDPNET.DataCore;
using ATEC.CCLObj.Entity;
using System.Windows.Forms;

namespace CCFWorkExample
{
    /// <summary>
    /// 文件名：ExtrinsicProperty.cs
    /// 分类：玄镜BIM图形平台/C#开发/示例代码/CCF属性操作/外部属性
    /// 
    /// 功能概述：
    /// 展示如何在玄镜平台中操作外部属性（Extrinsic Property），包括添加、查询和删除等操作。
    /// 
    /// 外部属性特点：
    /// 1. 独立存储：
    ///    - 属性值独立于对象本身存储
    ///    - 可以动态添加和移除
    ///    - 不影响原有对象结构
    /// 
    /// 2. 灵活管理：
    ///    - 支持按类型查询属性
    ///    - 支持批量查询和删除操作
    ///    - 支持属性的选择性删除
    /// 
    /// 3. 场景关联：
    ///    - 通过ATAttachment与场景对象关联
    ///    - 支持跨对象的属性管理
    ///    - 便于统一维护和更新
    /// 
    /// 主要操作：
    /// 1. GetATAttachment：获取场景附件
    /// 2. AddProp：添加外部属性
    /// 3. QueryProp：查询特定类型的属性
    /// 4. QueryAllProp：查询所有外部属性
    /// 5. RemoveProp：移除特定属性
    /// 6. RemoveAllProp：移除所有属性
    /// 
    /// 使用场景：
    /// 1. 需要动态添加属性信息
    /// 2. 需要跨对象共享属性数据
    /// 3. 需要批量管理属性
    /// 
    /// 注意事项：
    /// 1. 操作前需要确保场景附件存在
    /// 2. 属性操作需要正确的CCF配置
    /// 3. 删除操作需要谨慎处理
    /// </summary>
    public class ExtrinsicProperty
    {
        /// <summary>
        /// 方法名：GetATAttachment
        /// 功能：获取当前场景的附件对象
        /// 返回值：ATAttachment，场景附件对象
        /// 处理流程：
        /// 1. 获取活动场景
        /// 2. 获取场景的所有附件
        /// 3. 返回第一个可用附件
        /// 
        /// 注意事项：
        /// - 如果没有附件，返回null
        /// - 只返回第一个附件，如需多个需要修改逻辑
        /// </summary>
        public static ATAttachment GetATAttachment()
        {
            ATScene scene = ATEC.ATCore.Session.Entity.GetActiveATScenes();
            var attachments = scene.GetATAttachments().ToList();
            if (attachments.Count == 0)
            {
                return null;
            }
            return attachments[0];
        }
        /// <summary>
        /// 方法名：AddProp
        /// 功能：向场景附件中添加外部属性
        /// 处理流程：
        /// 1. 获取场景附件
        /// 2. 获取CCF属性管理器
        /// 3. 创建属性实例
        /// 4. 设置属性值
        /// 5. 添加到附件中
        /// 
        /// 注意事项：
        /// - 需要正确配置CCF工作集和属性结构名称
        /// - 添加前检查附件和使能器是否有效
        /// - 属性值需要符合定义的类型
        /// </summary>
        public static void AddProp()
        {
            var attach = GetATAttachment();  // 获取场景附件
            if(attach==null)  // 检查附件是否存在
            {
                return;
            }
            ATCCLManager manger = ATCCLManager.Manager;  // 获取CCF管理器实例
            ATCCLEntityEnabler enaber = manger.ObtainEntityEnablerByName(
                CCFWorkTestStruct.cclName, 
                CCFWorkTestStruct.cclanName, 
                ATEC.ATCore.Session.Entity.GetActiveATProject());  // 获取属性使能器
            
            if (enaber == null)  // 检查使能器是否有效
            {
                return;
            }
            var entity = enaber.SharedWipInstance;  // 获取共享的工作实例
            entity.SetValue("Length", 100.0);  // 设置长度属性值
            var res=attach.AddExtrinsicProperty(entity);  // 添加外部属性
        }

        /// <summary>
        /// 方法名：QueryProp
        /// 功能：查询特定类型的外部属性
        /// 处理流程：
        /// 1. 获取场景附件
        /// 2. 按CCF类型查询属性
        /// 3. 读取属性值
        /// 4. 显示查询结果
        /// 
        /// 注意事项：
        /// - 查询前检查附件是否存在
        /// - 处理查询结果可能为空的情况
        /// - 正确解析属性值的类型
        /// </summary>
        public static void QueryProp() 
        {
            var attach = GetATAttachment();  // 获取场景附件
            if (attach == null)  // 检查附件是否存在
            {
                return;
            }
            var props = attach.QuerySpecificExtrinsicProperties(
                CCFWorkTestStruct.cclName, 
                CCFWorkTestStruct.cclanName);  // 查询特定类型的属性
            
            if (props.Count() == 0)  // 检查是否存在查询结果
            {
                return;
            }
            var builder=new StringBuilder();  // 创建字符串构建器    
            foreach (var prop in props)  // 遍历所有属性
            {
                builder.AppendFormat($"Length={prop.GetDouble("Length")} {Environment.NewLine}");  // 格式化属性值
                MessageBox.Show(builder.ToString());  // 显示属性值
            }
        }

        /// <summary>
        /// 方法名：QueryAllProp
        /// 功能：查询所有外部属性
        /// 处理流程：
        /// 1. 获取场景附件
        /// 2. 查询所有外部属性
        /// 3. 根据属性类型分别处理
        /// 4. 显示查询结果
        /// 
        /// 注意事项：
        /// - 需要处理不同类型的属性
        /// - 属性值的类型判断和转换
        /// - 结果格式化和显示
        /// </summary>
        public static void QueryAllProp()
        {
            var attach = GetATAttachment();  // 获取场景附件
            if (attach == null)  // 检查附件是否存在
            {
                return;
            }
            var props = attach.QueryAllExtrinsicProperties();  // 查询所有外部属性
            if (props.Count() == 0)  // 检查是否存在查询结果
            {
                return;
            }
            var builder=new StringBuilder();  // 创建字符串构建器
            foreach (var prop in props)  // 遍历所有属性
            {
                if(prop.ClassDefinition.Name== CCFWorkTestStruct.cclanName)  // 检查属性类型
                {
                    builder.AppendFormat($"Length = {prop.GetDouble("Length")} {Environment.NewLine}");  // 格式化长度属性
                }
                else
                {
                    builder.AppendFormat($"id={prop.GetString("id")} {Environment.NewLine}");  // 格式化ID属性
                }
            }
            MessageBox.Show(builder.ToString());  // 显示所有属性值
        }

        /// <summary>
        /// 方法名：RemoveProp
        /// 功能：移除特定类型的外部属性
        /// 处理流程：
        /// 1. 获取场景附件
        /// 2. 查询指定类型的属性
        /// 3. 删除找到的第一个属性
        /// 
        /// 注意事项：
        /// - 删除前检查附件是否存在
        /// - 确保要删除的属性存在
        /// - 只删除第一个匹配的属性
        /// - 需要谨慎使用，确保不会误删重要数据
        /// 
        /// 相关方法：
        /// - GetATAttachment：获取场景附件
        /// - QuerySpecificExtrinsicProperties：查询特定类型属性
        /// - DeleteExtrinsicProperty：删除单个属性
        /// </summary>
        public static void RemoveProp()
        {
            var attach = GetATAttachment();  // 获取场景附件
            if (attach == null)  // 检查附件是否存在
            {
                return;
            }
            var props = attach.QuerySpecificExtrinsicProperties(
                CCFWorkTestStruct.cclName, 
                CCFWorkTestStruct.cclanName);  // 查询特定类型的属性
            
            if(props.Count()==0)  // 检查是否存在要删除的属性
            {
                return;
            }
            var res = attach.DeleteExtrinsicProperty(props.First());  // 删除第一个匹配的属性
        }

        /// <summary>
        /// 方法名：RemoveAllProp
        /// 功能：移除所有外部属性
        /// 处理流程：
        /// 1. 获取场景附件
        /// 2. 查询所有外部属性
        /// 3. 批量删除所有属性
        /// 
        /// 注意事项：
        /// - 删除前检查附件是否存在
        /// - 确保有属性需要删除
        /// - 此操作会删除所有类型的外部属性
        /// - 操作不可撤销，需要谨慎使用
        /// 
        /// 相关方法：
        /// - GetATAttachment：获取场景附件
        /// - QueryAllExtrinsicProperties：查询所有属性
        /// - DeleteAllExtrinsicProperties：删除所有属性
        /// 
        /// 使用场景：
        /// - 需要清理所有外部属性数据
        /// - 重置场景附件状态
        /// - 批量属性管理
        /// </summary>
        public static void RemoveAllProp()
        {
            var attach = GetATAttachment();  // 获取场景附件
            if (attach == null)  // 检查附件是否存在
            {
                return;
            }
            var props = attach.QueryAllExtrinsicProperties();  // 查询所有外部属性
            if (props.Count() == 0)  // 检查是否存在要删除的属性
            {
                return;
            }
            var res = attach.DeleteAllExtrinsicProperties();  // 删除所有外部属性
        }
    }
}
